package se.ytterman.jserial.util;

import java.lang.*;
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;

public class DOMUtil {
    // Parse XML file into DOM Document
    public static Document parseXMLFile(String fileName) throws Exception{ 
         // Open XML config file    
         File xmlModel = new File(fileName);
                    
         // Create DOM tree from file   
         DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
         Document domModel = domBuilder.parse(xmlModel);

         return domModel;
    }
    
    public static void printDOMTree(Node node, int indent) {
        
        if(node != null) {
            // Do indentation...
            for(int i = 0; i < indent; i++)
                System.out.print("\t");
            
            // Print node...
            DOMUtil.printNode(node);
        
            // Increase indentation
            indent++;
            
            // Get children
            NodeList childNodes = node.getChildNodes();
            int children = childNodes.getLength();
                        
            // Iterate and recurse...
            for(int i = 0; i < children; i++) {
                // Get node...
                Node nextNode = childNodes.item(i);
                // Recurse...
                DOMUtil.printDOMTree(nextNode, indent);
            }       
        }
        else {
            return;
        }
    }
        
    // Recurseivelry print DOM tree
    public static void printNode(Node node) {
        // Check if we're reached the leaf level...
        if(node != null) {          
            // Get node type    
            short type = node.getNodeType();
            
            switch(type) {
                case Node.ATTRIBUTE_NODE:
                    // The node is an Attr.
                    System.out.println("ATTRIBUTE_NODE: " + 
                                       node.getNodeName() + 
                                       " = " + 
                                       node.getNodeValue());
                    break;
                    
                case Node.CDATA_SECTION_NODE:
                    // The node is a CDATASection.
                    System.out.println("CDATA_SECTION_NODE: " + 
                                       node.getNodeName() + 
                                       " = " + 
                                       node.getNodeValue());
                    break;
                        
                case Node.COMMENT_NODE:
                    // The node is a Comment.
                    System.out.println("COMMENT_NODE: " + 
                                       node.getNodeName() + 
                                       " = " + 
                                       node.getNodeValue());
                    break;  
                    
                case Node.DOCUMENT_FRAGMENT_NODE:
                    // The node is a DocumentFragment.
                    break;
                    
                case Node.DOCUMENT_NODE:
                    // The node is a Document.
                    System.out.println("DOCUMENT_NODE: " + 
                                       node.getNodeName() + 
                                       " = " + 
                                       node.getNodeValue());
                    break;
                                 
                case Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC:
                    // The determination of preceding versus following 
                    // is implementation-specific.
                    break;
                                     
                case Node.DOCUMENT_TYPE_NODE:
                    // The node is a DocumentType.
                    break;
                    
                case Node.ELEMENT_NODE:
                    // The node is an Element.
                    System.out.println("ELEMENT_NODE: " + 
                                       node.getNodeName());
                    break;
                    
                case Node.ENTITY_NODE:
                    // The node is an Entity.
                    break;
                    
                case Node.ENTITY_REFERENCE_NODE:
                    // The node is an EntityReference.
                    break;
                    
                case Node.NOTATION_NODE:
                    // The node is a Notation.
                    break;
                    
                case Node.PROCESSING_INSTRUCTION_NODE:
                    // The node is a ProcessingInstruction.
                    break;
                    
                case Node.TEXT_NODE:
                    // The node is a Text node.
                    System.out.println("TEXT_NODE: " +  
                                       node.getNodeName() + " : " +
                                       node.getNodeValue());
                    break;
                    
                default:
                    // Default fallback
                    System.out.println("DEFAULT: " + 
                                       node.getNodeName() + 
                                       " = " + 
                                       node.getNodeValue());
            }
                

        }
        else {
            return;
        }
    }
}
